package com.homework.ch10;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * @author yuxi
 * @version 1.0
 * @date 2025/10/14
 * @Description:
 */
class Account{
    //账户名称、账户余额
    private String name;
    private double balance;
    //构造
    public Account(String name,double balance){
        this.balance = balance;
        this.name=name;
    }

    public String getName(){
        return name;
    }

    public double getBalance() {
        return balance;
    }

    //存钱+
    public void deposit(double amount){
        this.balance+=amount;
    }
    //取钱-
    public void withdraw(double amount){
        this.balance -= amount;
    }
    //转账 A->B  this->B  this->to
    public void transfer(Account to,double amount){
        //this,to 账户名称的排序 first second
        Account first = this;
        Account second = to;
        if (this.name.compareTo(to.name)<0)
        {
            first = to;
            second = this;
        }
        synchronized (first){
            synchronized (second){
                if (this.balance>amount){
                    this.withdraw(amount);
                    to.deposit(amount);
                    //输出信息
                    System.out.println(this.name+"转账给："+to.getName());
                    System.out.println(this);
                    System.out.println(to);
                }
                //this金额>amount
                //this-
                //to+
            }
        }
    }
    @Override
    public String toString(){
        return "["+this.name+"存款"+this.balance+"]";
    }
}
class Bank{
    //集合：多个账户
    public ArrayList<Account> accountList=new ArrayList<>();
    //构造器
    public  Bank(ArrayList<Account> accountList){
        this.accountList=accountList;
    }
    //转账平台
    public void transfer(Account from,Account to,double amount){
        from.transfer(to,amount);
    }
}
public class Test9 {
    public static void main(String[] args) {
        //创建多个账户N，放到集合里，构建银行1

        Account account1 = new Account("wukong",1000.0);
        Account account2 = new Account("wujing",3000.0);
        Account account3 = new Account("shaseng",5000.0);
        Account account4 = new Account("bailongma",1500.0);
        Account account5 = new Account("tangseng", 2000.0);
        ArrayList<Account> accounts = new ArrayList<>();
        accounts.addAll(Arrays.asList(account1,account2,account3,account4,account5));
        Bank bank = new Bank(accounts);

        //bank.accountList
        //随机转账
        Random random = new Random();
        List<Thread> ths=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Thread t=new Thread(()->{
                int formIndex = random.nextInt(5)  ;
                int toIndex = random.nextInt(5)  ;
                double randomAmount = random.nextInt(500);
                Account from=bank.accountList.get(formIndex);
                Account to=bank.accountList.get(toIndex);
                bank.transfer(from,to,randomAmount);

            });
            ths.add(t);
        }

        ths.forEach(t->t.start());

        //模拟死锁
        new Thread(){
            public void run(){
                System.out.println("111");
                synchronized (account1){
                    System.out.println("1已经拿到1锁");
                    synchronized (account2){
                        System.out.println("1已经拿到2锁");
                        System.out.println("1先锁1再锁2");
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }.start();

        new Thread(){
            public void run(){
                System.out.println("222");
                synchronized (account2){
                    System.out.println("2已经拿到2锁");
                    synchronized (account1){
                        System.out.println("2已经拿到1锁");
                        System.out.println("1先锁2再锁1");
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }.start();
    }
}